package com.example.gybicycle.controller.wx;

import com.example.gybicycle.common.entity.Result;
import com.example.gybicycle.common.util.*;
import com.example.gybicycle.common.wxPay.WechatPayExternalService;
import com.example.gybicycle.entity.*;
import com.example.gybicycle.entity.wx.BikePointCount;
import com.example.gybicycle.entity.wx.OpenLock;
import com.example.gybicycle.entity.wx.WXLoginInfo;
import com.example.gybicycle.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

@Tag(name = "微信骑行")
@RestController
@RequestMapping("/wx/cycling")
public class CyclingController {
    @Autowired
    private LockService lockService;
    @Autowired
    private BikeService bikeService;
    @Autowired
    private BikePointService pointService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private BikeFailureService failureService;
    @Autowired
    private MemberDepositService depositService;
    @Autowired
    private MemberOrderService orderService;
    @Autowired
    private MemberPayService memberpayService;
    @Autowired
    private  WechatPayExternalService wxpayService;
    @Autowired
    private PayService payService;
    @Autowired
    private MemberInsureService memberInsureService;
    @PostMapping("/paydeposit")
    @Operation(summary = "支付押金")
    public Result payDeposit(@RequestBody OpenLock openLock, HttpServletRequest request){
        WXLoginInfo info=LoginUtil.getWxLoginInfo(request);
        if(info==null)
            return Result.fail("请获取用户信息");
//        Lock lock=lockService.get(openLock.getLockId());
        Bike bike=bikeService.get(openLock.getBikeId());
        if( bike==null)
            return Result.fail("当前未获取到车辆编号");
        if(bike.getLatchNo()==null||bike.getLatchNo().length()==0)
            return Result.fail("当前车辆未绑定插销,不能使用");
        if( bike.getLockId()==null)
            return Result.fail("当前车辆未上锁");
        Lock lock=lockService.get(bike.getLockId());
//        创建订单
        String point=lockService.findPointName(lock.getId());
        MemberOrder order =new MemberOrder();
        order.setBikeId(openLock.getBikeId());
        order.setOrderState(8);
        order.setMemberId(info.getId());
        order=orderService.getOne(order);
        int num=0;
        if(order==null){
             order=CyclingUtil.createOrder(openLock,bike.getId(),info.getId(),point);
             order.setOrderState(8);
             num=orderService.insert(order);
            if(num<1)
                return Result.fail("订单创建失败");
        }
        MemberDeposit deposit=depositService.getByNumber(order.getId());
        if(deposit==null){
            //        押金创建
             deposit=CyclingUtil.createDeposit(order.getId(),info.getId());
            num=depositService.insert(deposit);
            if(num<1) {
                orderService.delete(order.getId());
                return Result.fail("押金创建失败");
            }
        }

        MemberPay pay=new MemberPay();
        pay.setMemberOrderId(order.getId());
        pay.setPayType(0);
        pay=memberpayService.getOne(pay);
        if(pay!=null){
            memberpayService.delete(pay.getId());
        }
        pay=NumberUtil.createPay(deposit,info.getWxOpenid());
        pay.setMemberOrderId(order.getId());
        num= memberpayService.insert(pay);
        if(num<0){
            return Result.fail("创建支付单失败");
        }
        pay.setMemberOrderId(deposit.getId());
        var re=wxpayService.prepayWithRequestPayment(pay);
        return Result.success(re);
    }


    @PostMapping("/openLock")
    @Operation(summary = "确认开锁")
    public Result openLock(@RequestBody OpenLock openLock, HttpServletRequest request){
        WXLoginInfo info=LoginUtil.getWxLoginInfo(request);
        if(info==null)
            return Result.fail("请获取用户信息");
        if(openLock.getBikeId()==null)
            return Result.fail("请传入车辆ID");
        Bike bike=bikeService.get(openLock.getBikeId());
        MemberOrder order=new MemberOrder();
        order.setBikeId(openLock.getBikeId());
        order.setOrderState(8);
        order.setMemberId(info.getId());
        order=orderService.getOne(order);
//        更新押金状态
        MemberDeposit deposit =new MemberDeposit();
        deposit.setMemberOrderId(order.getId());
        deposit.setDepositState(0);
        depositService.updateByOrder(deposit);
        boolean isopen=true;
        if(bike==null||bike.getLockId()==null){
            isopen=false;
        }
        try{
            if(isopen){
                Lock lock=lockService.get(bike.getLockId());
                BiCycleUtil.openLock(lock.getCid(),lock.getMainId(),info.getId());
            }
        }catch (Exception e){
            e.printStackTrace();
            isopen=false;
        }
        if(!isopen){
            payService.refund(order.getId());
            order.setOrderState(6);
            order.setEndTime(new Date());
            orderService.update(order);
            return Result.fail("开锁失败,请重新选择车辆进行开锁");
        }
        order.setStartTime(new Date());
        order.setOrderState(0);
        orderService.update(order);
        order.setTimes(DataUtil.DurationTimes(order.getStartTime(),new Date()));
        order.setPayMoney(PayUtil.getPrice(order));
       return Result.success(order);
    }
    @PostMapping("/closeLock")
    @Operation(summary = "确认关锁")
    public Result closeLock(@RequestBody OpenLock openLock, HttpServletRequest request){
        WXLoginInfo info=LoginUtil.getWxLoginInfo(request);
        if(info==null)
            return Result.fail("请获取用户信息");
       MemberOrder order=orderService.get(openLock.getMemberOrderId());
       Bike bike=bikeService.get(order.getBikeId());
       if(bike.getBikeState().equals(1))
           return Result.fail("当前单车未关锁，请关锁成功后再进行确认");
       order.setOrderState(1);
       order.setEndTime(new Date());
       order.setDuration(DataUtil.Duration(order.getStartTime(),order.getEndTime()));
        String point=lockService.findPointName(bike.getLockId());
        order.setEndPoint(point);
        //       关闭订单
        int num=orderService.update(order);
        if(num==0)
            return Result.fail("关闭订单失败");

//        创建支付单
        MemberPay pay=new MemberPay();
        pay.setMemberOrderId(order.getId());
        pay.setPayType(1);
        pay=memberpayService.getOne(pay);
        if(pay==null){
             pay=NumberUtil.createPay(order,info.getWxOpenid());
            order.setCyclingMoney(pay.getMoney());
            order.setPayMoney(pay.getMoney());
            pay.setMoney(order.getCyclingMoney());
            num=memberpayService.insert(pay);
        }

        if(num>0){
            try{
                var re=wxpayService.prepayWithRequestPayment(pay);
                return Result.success(re);
            }catch (Exception e){
                pay=NumberUtil.createPay(order,info.getWxOpenid());
                order.setCyclingMoney(pay.getMoney());
                order.setPayMoney(pay.getMoney());
                pay.setMoney(order.getCyclingMoney());
                num=memberpayService.insert(pay);
                var re=wxpayService.prepayWithRequestPayment(pay);
                return Result.success(re);
            }


        } else return Result.fail("确认关锁失败");
    }
    @PostMapping("/confirmClose")
    @Operation(summary = " 确认关闭")
    public Result close(@RequestBody OpenLock openLock, HttpServletRequest request){
        var order=orderService.get(openLock.getMemberOrderId());
        return Result.success(order);
    }

    @PostMapping("/point")
    @Operation(summary = "点位")
    public Result<List<BikePointCount>> point(HttpServletRequest request){
        List<BikePointCount> list=pointService.findPoint();
// 车辆信息
        return Result.success(list);
    }
    @PostMapping("/failure")
    @Operation(summary = "故障提交")
    public Result update(@RequestBody BikeFailure failure, HttpServletRequest request){
        WXLoginInfo info=LoginUtil.getWxLoginInfo(request);
        if(info==null)
            return Result.fail("请获取用户信息");
        if(failure.getMemberOrderId()==null)
            return Result.fail("未获取到订单ID");
        int num= failureService.failureOrderNum(failure.getMemberOrderId());
        if(num>0)
            return Result.fail("当前订单已提交故障");
        failure.setFailureState(0);
        if(failure.getBikeId()==null){
            MemberOrder order=orderService.get(failure.getMemberOrderId());
            failure.setBikeId(order.getBikeId());

        }

        failure.setFailureTime(new Date());
         num=failureService.insert(failure);
         orderService.closeOrder(failure.getMemberOrderId());

        if(num>0)
            return Result.success("故障提交成功,等待工作人员确认故障后支付订单金额");
        else return Result.fail("故障提交失败");
    }
    @PostMapping("/ordering")
    @Operation(summary = "进行中订单")
    public Result ordering(HttpServletRequest request){
        WXLoginInfo info=LoginUtil.getWxLoginInfo(request);
        if(info==null)
            return Result.loginOut();
        MemberOrder order=new MemberOrder();
        order.setMemberId(info.getId());
        order.setOrderState(0);
        List<MemberOrder> orders=orderService.findList(order);
        for(MemberOrder order1:orders){
            Date date=order1.getEndTime();
            if(date==null)
                date=new Date();
            order1.setDuration(DataUtil.Duration(order1.getStartTime(),date));
            order1.setPayMoney(PayUtil.getPrice(order1));
            order1.setTimes(DataUtil.DurationTimes(order1.getStartTime(),date));

        }
        return Result.success(orders);
    }
}
